/*********************************************************
*
*  FJH-sim v1.0
*  Copyright � 2008 H.Y. Bruintjes, J.H. Donker,
*  C.E. Etheredge
*
*  Simulator node class
*
**********************************************************/

#include "node/SimNode.h"
#include "simulator/Simulator.h"
#include "shared/Utils.h"

#include <stdio.h>
#include <unistd.h>
#include <poll.h>

#include <iostream>

SimNode::SimNode(NodeAddress address)
: Node::Node(address)
{
	pipeContents = 0;
}

SimNode::~SimNode()
{
	//::close(m_pipe[0]);
	//::close(m_pipe[1]);
}

bool SimNode::open()
{
	//we have nothing to do
	return true;
}

bool SimNode::send(const char* data, unsigned int length)
{
	debug_print("SimNode", "Sending");
	using namespace std;
	
	if (m_listener)
		m_listener->dataArrived(data, length);
	
	debug_print("SimNode", "Created event");
	return true;
}

int SimNode::receive(char* data, unsigned int length)
{
	//there is no buffering layer since SimNode does this with its own pipe (no additional threads may be started)
	return receive_sync(data, length);
}

inline int min(int i1, int i2) {
	return (i1 < i2)?i1:i2;
}

int SimNode::receive_sync(char* data, unsigned int length)
{
	if (length < PACKET_SIZE)
		return -1;
		
	if (m_packets.size() == 0)
		return -1;
		
	packet & pckt = m_packets.front();
	
	int toCopy = min(pckt.size, length);
	memcpy(data, pckt.data, toCopy);
	delete [] pckt.data;
	m_packets.pop();
	
	return toCopy;
/*
	int packetSize = 0;
	size_t res = read(m_pipe[0], &packetSize, sizeof(int));
	pipeContents -= res;
	res = read(m_pipe[0], data, packetSize);
	pipeContents -= res;
	return (int)res;
*/
}

bool SimNode::poll() 
{
	return m_packets.size() > 0;
	//return pipeContents > 0;
/*
	struct pollfd pfd;
	
	pfd.fd		= m_pipe[0];
	pfd.events	= POLLIN;
	pfd.revents	= 0;
	
	::poll(&pfd,sizeof(pfd),0);
	return (pfd.revents & POLLIN);
*/
}

void SimNode::inject(const char* data, int length)
{
	if (length) {
		char * ddata = new char[length];
		memcpy(ddata, data, length);
		packet pckt;
		pckt.size = length;
		pckt.data = ddata;
		m_packets.push(pckt);
	}
/*
	if (length) {
		if (pipeContents+length > 4096) {
			error_print("SimNode", "Pipe full, aborting insert to prevent deadlock");
			return;
		}
		debug_print("SimNode", "Injecting");
		write(m_pipe[1], &length, sizeof(int));	// write one integer with size of packet
		pipeContents += sizeof(int);
		write(m_pipe[1], data, length);
		pipeContents += length;
	}
*/
}


void SimNode::close()
{
	// that just like your opion man.
}

